/*
 *    Copyright (c) 2018-2025, nart All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: nart
 */

package com.nai365.nart.order.controller;

import cn.hutool.core.lang.Console;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nai365.nart.common.core.constant.SecurityConstants;
import com.nai365.nart.common.core.util.R;
import com.nai365.nart.common.excel.annotation.ResponseExcel;
import com.nai365.nart.common.log.annotation.SysLog;
import com.nai365.nart.common.security.annotation.Inner;
import com.nai365.nart.common.security.util.SecurityUtils;
import com.nai365.nart.member.feign.RemoteMemberService;
import com.nai365.nart.order.entity.Order;
import com.nai365.nart.order.entity.OrderItem;
import com.nai365.nart.order.service.OrderItemService;
import com.nai365.nart.order.service.OrderService;
import com.nai365.nart.order.to.PayOrderTo;
import com.nai365.nart.order.vo.OrderSubmitVO;
import com.nai365.nart.order.vo.SubmitOrderResponseVO;
import com.nai365.nart.pay.entity.ProductDetail;
import com.nai365.nart.pay.feign.RemoteUpayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

/**
 * 订单
 *
 * @author baogs
 * @date 2022-07-01 14:19:39
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/order" )
@Api(value = "order", tags = "订单管理")
public class OrderController {

    private final  OrderService orderService;
    private final OrderItemService orderItemService;

	private final RemoteUpayService remoteUpayService;

    /**
     * 分页查询
     * @param page 分页对象
     * @param order 订单
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page" )
    public R getOrderPage(Page page, Order order) {
        return R.ok(orderService.page(page, Wrappers.query(order)));
    }

	/**
	 * 分页查询当前登录用户的所有订单信息
	 * @param order
	 * @return
	 */
	@GetMapping("/listWithItem")
	@ApiOperation(value = "分页查询当前登录用户的所有订单信息", notes = "type 传0或空为查询买入订单，1为卖出订单，2为流转记录")
	public R listWithItem(Page page, Order order,Integer type){
		return R.ok(orderService.queryPageWithItem(page, order,type));
	}



	/**
	 * 分页模糊查询
	 * @param page     分页模糊查询
	 * @param order 订单
	 * @return
	 */
	@ApiOperation(value = "分页模糊查询", notes = "分页模糊查询")
	@GetMapping("/queryOrderPage")
	public R queryOrderPage(Page page, Order order, String key) {
		return R.ok(orderService.page(page,Wrappers.lambdaQuery(order).like(Order::getOrderSn, key)));
	}

    /**
     * 通过id查询订单
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}" )
    public R getById(@PathVariable("id" ) String id) {
        return R.ok(orderService.getById(Long.parseLong(id)));
    }
    /**
     * 通过id查询订单详情带订单项
     * @param orderSn id
     * @return R
     */
    @ApiOperation(value = "通过id查询订单详情带订单项", notes = "通过id查询订单详情带订单项")
    @GetMapping("/info" )
    public R getInfoById(@RequestParam("orderSn" ) String orderSn) {
		Order byId = orderService.getOrderByOrderSn(orderSn);
		if(byId == null) {
			return R.failed("订单处理中，请到我的订单中查看");
		}
		List<OrderItem> list = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderSn));
		byId.setOrderItemEntityList(list);
		return R.ok(byId);
    }

    /**
     * 新增订单
     * @param order 订单
     * @return R
     */
    @ApiOperation(value = "新增订单", notes = "新增订单")
    @SysLog("新增订单" )
    @PostMapping
    public R save(@RequestBody Order order) {
        return R.ok(orderService.save(order));
    }

    /**
     * 新增订单
     * @param payOrderTo 订单
     * @return R
     */
    @ApiOperation(value = "新增订单", notes = "新增订单")
    @SysLog("新增订单" )
    @PostMapping("/callback")
	@Inner(value = false)
    public R callBack(@RequestBody PayOrderTo payOrderTo) {
		Console.log("####",payOrderTo);
        return R.ok(payOrderTo);
    }

    /**
     * 用订单号支付
     * @param orderSn 订单
     * @return R
     */
    @ApiOperation(value = "用订单号支付", notes = "用订单号支付")
    @SysLog("用订单号支付" )
    @GetMapping("/pay_ordersn")
	@Inner(value = false)
    public R save(@RequestParam String orderSn) {
		Order orderByOrderSn = orderService.getOrderByOrderSn(orderSn);
		OrderItem one = orderItemService.getOne(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderSn, orderSn));
		com.nai365.nart.pay.entity.Order order = new com.nai365.nart.pay.entity.Order();
		order.setRequestId(orderSn);
		order.setOrderAmount(orderByOrderSn.getTotalAmount().multiply(BigDecimal.valueOf(100)).intValue()+"");
		ProductDetail productDetail = new ProductDetail();
		productDetail.setAmount((long)one.getSkuPrice().multiply(BigDecimal.valueOf(100)).intValue());
		productDetail.setName(one.getSkuName());
		productDetail.setQuantity(one.getSkuQuantity().longValue());
		order.setProductDetails(productDetail);

		return remoteUpayService.payOrder(order, SecurityConstants.FROM_IN);
    }

    /**
     * 提交订单
     * @param orderSn 订单
     * @return R
     */
    @ApiOperation(value = "提交订单", notes = "提交订单")
    @SysLog("用订单号支付" )
    @PostMapping("/submit")
    public R submit(@RequestBody OrderSubmitVO orderSubmitVO) {
		Long userId = SecurityUtils.getUser().getId();
		boolean b = orderService.checkNoPay(userId);
		if (b) {
			return R.failed("有未支付订单，请支付后再下单");
		}
		SubmitOrderResponseVO submitOrderResponseVO =null;
		try {
			submitOrderResponseVO = orderService.submitOrder(orderSubmitVO);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return R.ok(submitOrderResponseVO);
    }




    /**
     * 修改订单
     * @param order 订单
     * @return R
     */
    @ApiOperation(value = "修改订单", notes = "修改订单")
    @SysLog("修改订单" )
    @PutMapping
    public R updateById(@RequestBody Order order) {
		boolean b = orderService.updateById(order);
		if (b){
			return R.ok(b,"修改成功");
		} else {
			return R.failed(b,"修改失败");

		}

    }

    /**
     * 通过id删除订单
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除订单", notes = "通过id删除订单")
    @SysLog("通过id删除订单" )
    @DeleteMapping("/{id}" )
    public R removeById(@PathVariable Long id) {
        return R.ok(orderService.removeById(id));
    }


    /**
     * 导出excel 表格
     * @param order 查询条件
     * @return excel 文件流
     */
    @ResponseExcel
    @GetMapping("/export")
    public List<Order> export(Order order) {
        return orderService.list(Wrappers.query(order));
    }


	/**
	 * 查询今日和全部订单金额
	 *
	 * @param rank rank
	 * @return R
	 */
	@ApiOperation(value = "查询今日和全部订单金额", notes = "查询今日和全部订单金额")
	@GetMapping("/getAllMoney")
	public R getAllMoney(@RequestParam("rank") Integer rank) {
		return R.ok(orderService.getAllMoney( rank));
	}

	/**
	 *
	 * @return
	 */
	@ApiOperation(value = "根据订单号查询订单", notes = "根据订单号查询订单")
	@GetMapping("/findOrderByOrderId/{orderSn}")
	@Inner
	public R<Order> findOrderByOrderId(@PathVariable("orderSn") String orderSn){
		Order order=orderService.findOrderByOrderId(orderSn);
		return R.ok(order);
	}


	/**
	 * 根据订单编号查询订单状态
	 * @param orderSn
	 * @return
	 */
	@GetMapping(value = "/status/{orderSn}")
	@Inner
	public R getOrderStatus(@PathVariable("orderSn") String orderSn) {
		Order orderEntity = orderService.getOrderByOrderSn(orderSn);
		return R.ok().setData(orderEntity);
	}

	@GetMapping("/modifyOrderStatus/{orderId}/{status}")
	@Inner
	public void modifyOrderStatus(@PathVariable("orderId") String orderId,@PathVariable("status") Integer status){
		orderService.updateOrderStatusByOserId(orderId,status);
	}
	@GetMapping("/check_no_pay")
	@Inner
	public R checkNoPay(Long userId){
		return R.ok(orderService.checkNoPay(userId));
	}


	/**
	 * 信息
	 */
	@GetMapping("/info/{id}")
	public R info(@PathVariable("id") Long id) {
		Order order = orderService.getById(id);

		return R.ok(order);
	}


}
